To foster the development of Shapes Constraint Language (SHACL), this document includes a set of use cases and requirements that motivate a simple language and semantics for formulating structural constraints on RDF graphs. All use cases provide realistic examples describing how people may use structural constraints to validate RDF instance data. Note, that this document avoids the use of any specific vocabulary that might be introduced by the SHACL specification.

Scope and Motivation

One motivation for SHACL is Application Integration, where different software components, potentially maintained by different organizations, need to function together smoothly. As an everyday example, imagine an international company with a dozen divisions, each providing a feed of their Human Resources data to authorized users. Different divisions might use different software to produce their feeds, and there might be many distinct applications which consume the data, ranging from an employee phone book to a hiring-compliance monitoring system.

While systems like this are built and maintained around the world today, their complexity often becomes a problem. Not only are the systems expensive and sometimes unpleasant to maintain, but changing data fields and adding new applications can grow to be practically impossible. An "RDF Data Shapes" standard would help manage the complexity, greatly reducing the cost and hassle, by separating components while still allowing them to work together.

Specifically, in this example, SHACL would allow:

In all cases, the semantics of the data are determined by RDF and the vocabularies specified by the shape, so if the shapes match, the systems can reasonably be expected to interoperate correctly.

While SHACL is expected to have immediate everyday utility, as illustrated above, it has even wider potential applicability, ranging in scale. At the large end, SHACL might be used by loosely-knit communities, where data is provided by organizations which are not under any central authority, such as charities and researchers around the world concerned with quality-of-life measures. At the small end, SHACL might be used within a mobile application environment to provide interoperability among independent sensor modules and tools for analyzing and acting on sensor results. The common thread is that SHACL allow a loose coupling, where independently maintained elements of an overall system can reliably and comfortably interoperate.

Organization of this Document

This document is organized as follows:

User Stories

S12: App interoperability

There is one application (eg Cimba) which stores application state in RDF. It currently queries and modifies that state using HTTP GET and PUT operations on RDF Sources, but we have another version being developed that uses SPARQL to query and modify the data. The question is, how do we communicate the shape of the data this application reads and writes to other developers who want to make compatible applications? We want to say: as long as your data is of this form, Cimba will read it properly. We also want to say: Cimba may write data of any of these forms, so to be interoperable, your application will need to read and correctly process all of them.

Summary: Requires the final "shape syntax" to be light-weight and less verbose than SPARQL.

Related Requirements: R5.1, R5.2, R5.3, R5.4, R5.9.1, R5.9.2, R5.9.3, R11.5, and R11.7

Use Cases

The following use cases are each derived from one or more of the user stories above. These use cases are explored in detail through their description and their related user stories and requirements. The examples they contain are included purely for illustrative purposes, and should not be interpreted normatively.

UC1: Defining constraints of properties or classes of an RDF graph

Description: This use case addresses the ability to constrain certain properties or classes of an RDF graph (i.e. defining their shape). For example, one could formalize the requirement that each property must have an associated domain or that each node of type X has to have required properties Y and Z. Being able to define and constrain shapes of entities in an RDF graph, allows to check whether that graph is valid wrt. to those defined constraints.

Related Use Cases: UC1, UC2,

Related Requirements:

Requirements

This section lists the requirements arising from the use-cases catalogued in this document. Specific requirements that have been de-prioritized or rejected have been left in the document for completeness, but are shown as struck out.

R1: Higher-Level Language

Constraints/shapes shall be specifiable in a higher-level language with 1. definitional capabilities, such as macro rolling up and naming, and 2. control infrastructure for, e.g., recursion.

Motivation: Dublin Core Requirement 103

R2: Concise Language

Constraints/shapes shall be specifiable in a concise language.

Motivation: Dublin Core Requirement 184

R3: Addressability

Collections of constraints/shapes may be addressable and discoverable. Individual constraints/shapes may be addressable and discoverable.

Motivation: Dublin Core Requirement 147 and Dublin Core Requirement 148

R4: Annotations

Constraints/shapes may incorporate extra information that does not affect validation. It shall be possible to search for constraints/shapes with particular extra information.

Motivation: Dublin Core Requirement 208

R5.1: Association of Class with Shape

There must be an "easy" way of associating a shape with a class, meaning that nodes in a graph that are instances of that class must conform with that shape

Motivation: UC3, UC10, UC11, UC12, UC13, UC15, UC19, UC20, UC29, and UC36

R5.2: Property Min/Max Cardinality

The stated values for a property may be limited by minimum/maximum cardinality, with typical patterns being [0..1], [1..1], [0..*] and [1..*].

Motivation: UC10, UC11, UC13, UC19, UC20, UC39, and UC42

R5.3: Property Datatype

The values of a property may be limited to be an RDF Literal with a stated datatype, such as xsd:string or xsd:date.

Motivation: UC10, UC11, UC13, UC19, and UC20

R5.4: Property Type

The values of a property may be limited by their type, e.g., all children have to be of type person.

Motivation: UC10, UC11, UC13, UC19, and UC20

R5.5: Property's RDF Node Type (e.g. only IRIs are allowed)

The values of a property on instances of a class may be limited by their RDF node type, e.g. IRI, BlankNode, Literal, or BlankNodeOrIRI (for completeness we may want to support all 7 combinations including Node as parent).

Motivation: UC8

R5.9.1: Datatype Property Facets: min/max values

Similar to xsd:minInclusive/maxExclusive

Motivation: UC3, UC11, UC12, UC13, UC19, UC20, and UC29

R5.9.2: Datatype Property Facets: regular expression patterns

Pattern matching against regular expressions (xsd:pattern).

Motivation: UC3, UC11, UC12, UC13, UC19, UC20, and UC29

R5.9.3: Datatype Property Facets: string length

Constraining the length of a string.

Motivation: UC3, UC11, UC12, UC13, UC19, UC20, and UC29

R5.10: Property Value Enumerations

Shapes will provide exhaustive enumerations of the valid values (literals and IRIs).

Motivation: UC3, UC11, and UC37

R5.11: Properties Used in Inverse Direction

Shapes can have constraints where the tested node is the object of a triple.

Motivation: UC36

R6: Complex Constraints

The language should allow users to implement constraints that check complex conditions, with an expressivity as covered by the following sub-requirements (e.g. basic graph patterns, string and mathematical operations and comparison of multiple values).

Motivation: UC5, UC21, UC22, UC23, UC26, UC27, and UC30

R6.2: Expressivity: Non-Existence of Patterns

Many constraints require that a certain pattern does not exist in the graph.

Motivation: UC1, UC2, UC22, and UC23

R6.3: Expressivity: String Operations

Some constraints require building new strings out of other strings, and building new URIs out of other values.

Motivation: UC5 and UC23

R6.4: Expressivity: Language Tags

Some constraints require comparing language tags of RDF literals, e.g. to check that no language is used more than once per property. Also to produce multi-lingual error messages.

Motivation: UC21, UC42

R6.5: Expressivity: Mathematical Operations

Some constraints require mathematical calculations and comparisons, e.g. area = width * height.

Motivation: UC5

R6.6: Expressivity: Literal Value Comparison

Some constraints require operators such as <, >=, != etc, either against constants or other values that are dynamically retrieved at query time. Includes date/time comparison and functions such as NOW().

Motivation: UC5, UC21, UC22, UC23, and UC27

R6.7: Expressivity: Logical Operators

The language should make it possible to express the basic logical operators intersection, union and negation of conditions.

Motivation: UC5, UC26, and UC35

R6.8: Expressivity: Transitive Traversal of Properties

Some constraints need to be able to traverse a property transitively, such as parent-child or partOf relationships.

Motivation: UC16, UC23, and UC26

R6.11: Expressivity: Closed Shapes

Some data recipients will not act as generic triple stores. "Closed shapes" identify triples not matched by a property constraint in a shape. A few uses of closed shapes: a client tests that every triple being sent to a server will be accepted/processed; a server rejects any document with unexpected triples; a server accepts and ignores unexpected triples and returns a list of dropped triples to the client. (The control can probably be applied to the whole schema rather than individual shapes. At least, there's no use case or implementation experience to the contrary.)

Motivation: UC4

R6.12: Expressivity: Checking for well-formed rdf:Lists

There shall be a concise construct for expressing that a list must be well-formed.

Motivation: UC42

This requirement has not been approved yet.

R6.13: Expressivity: Placing constraints on the values of rdf:Lists

There shall be a way of applying the constraints that we can express for normal properties (require a certain rdf:type, require a certain shape, require a certain datatype, require a certain node kind, etc.) to the members of rdf:Lists.

Motivation: UC42

This requirement has not been approved yet.

R7: Macro-Language Features

The language should enable the definition of macros as short cuts to recurring patterns, and to enable inexperienced users define rich constraints. Macros should be high-level terms that improve overall readability, separation of concerns and maintainability. This overlaps with the already approved "Higher-Level Language".

Motivation: UC5, UC16, UC21, UC27, UC28, and UC32

R7.1: Named Shapes

It should be possible to encapsulate a group of constraints (a Shape) into a named entity, so that the Shape can be reused in multiple places, also across the Web

Motivation: UC16 and UC28

R7.2: Function and Property Macros

In order to support maintainable and readable constraints, it should be possible to encapsulate recurring patterns into named entities such as functions and dynamically computed properties. This requirement is orthogonal to almost every user story. It includes a vocabulary to share function definitions.

Motivation: UC5, UC16, and UC28

R7.3: Constraint Macros

Some constraint patterns are recurring with only slight modifications. Example: SKOS constraints that multiple properties must be pairwise disjoint. The language should make it possible to encapsulate such recurring patterns in a parameterizable form. Examples include SPIN/LDOM Templates.

Motivation: UC21, UC27, and UC28

R7.4: Nested Constraint Macros

It should be possible to combine the high-level terms of the constraint language into larger expressions using nested constraints. Examples of this include ShEx, Resource Shapes' oslc:valueShape and owl:allValuesFrom.

Motivation: UC32 and UC33

R8: Specialization of Shapes

It should be possible to specialize/extend shapes so that the constraints defined for a more general (super) shape also apply to the specialized (sub) shape. Sub-shapes can only narrow down, i.e. further constrain.

Motivation: UC2, UC5, UC10, UC11, UC19, UC20, UC24, UC25, UC27, UC28, and UC29

R9: Global Constraints

It should be possible to specify constraint conditions that need to be checked "globally" for a whole graph, without referring to a specific set of resources or class. In programming languages such global entities are often called "static", but "global" is probably better known.

Motivation: UC35

R10: Vocabulary for Constraint Violations

Instead of just reporting yes/no, the language needs to be able to return more meaningful messages including severity levels, human-readable error descriptions and pointers at specific patterns in the graph.

Motivation: UC3, UC34, and (almost every other use case)

R10.1: Severity Levels

The language should allow the creation of error responses that can include severity levels as desired.

Motivation: UC3

R10.2: Human-readable Violation Messages

The language should make it possible for constraint checks to create human-readable violation messages that can be either created explicitly by the user or generated dynamically from constraint definition. It should be possible to create such messages in multiple languages.

Motivation: UC3

R10.3: Constraint Violations should point at Specific Nodes

The language should make it possible for authors of constraint checks to produce pointers at specific nodes and graph fragments that caused the violation. Typical examples of such information includes the starting point (root node), a path from the root, and specific values that caused the problem.

Motivation: UC3

R11.5: Profiles

The language should include a notion of profiles, so that certain applications with limited features can only use certain elements of the overall language.

Motivation: UC11, UC19 and UC32

R11.7: Separation of structural from complex constraints

There shall be a core language or SHACL profile that excludes any support for constraints defined via embedded SPARQL queries or other complex lower-level expressions. This is so that lightweight applications can validate constraints without requiring a SPARQL processor or similar subsystem.

Motivation: UC11, UC19 and UC32

R11.8: Evaluating Constraints for a Single Node Only

It should be possible to validate constraints on a single node in a graph. This may be impossible to implement 100% correctly, because sometimes a change to a resource invalidates conditions in a very different place in the graph. However, the language could propose a framework that identifies those constraints that SHOULD be checked when a given node is evaluated, e.g. by following its rdf:type and the superclasses of that. This would include validating shacl:valueShape but not shacl:valueType.

Motivation: (Orthogonal to basically all use cases)

R12.1: Select Whole Graph

It should be possible to select all the RDF nodes in a graph for validation. This is similar to the Global Constraints (R9) requirement.

Motivation: UC35

R12.2: Selection by Type

It should be possible to have some mechanism to select the nodes that are instances of some class for validation.

Motivation: (Orthogonal to basically all stories)

R12.3: Selection by Single Node

It should be possible to select a single RDF node for validation.

Motivation: (Orthogonal to basically all stories)

R14.1: Property Default Value

It should be possible to provide a default value for a given property, e.g. so that input forms can be pre-populated. This requirement is not about using default values as "inferred" triples at run-time.

Motivation: UC11, UC19, and UC20

R14.2: Property Labels at Shape

It should be possible to provide human-readable labels of a property in the context of a shape, intended for human consumption such as documentation or UI, not just globally for the rdf:Property. Multiple languages should be supported.

Motivation: UC11 and UC19

R14.3: Property Comment in a Shape

It should be possible to provide human-readable descriptions of the role of a property in the context of a shape, not just globally using triples that have the rdf:Property as subject. Multiple languages should be supported.

Motivation: UC11 and UC19

Acknowledgements

We would like to acknowledge the contributions of user story authors: Dean Allemang, Anamitra Bhattacharyya, Karen Coyle, Nick Crossley, Michel Dumontier, Jose Emilio Labra Gayo, Sandro Hawke, Dimitris Kontokostas, Holger Knublauch, David Martin, Dave McComb, Peter F. Patel-Schneider, Axel Polleres, Eric Prud'hommeaux, Arthur Ryman, Steve Speicher, and Simon Steyskal.